#if UNITY_EDITOR
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
namespace VRChatAvatarToolkit {
    public class QuickDressed : MoyuToolkitUtils {
        private Vector2 mainScrollPos;
        private GameObject avatar, cloth;
        private bool overlayMode = true;

        private void OnGUI()
        {
            mainScrollPos = GUILayout.BeginScrollView(mainScrollPos);
            GUILayout.Space(10);
            GUI.skin.label.fontSize = 24;
            GUI.skin.label.alignment = TextAnchor.MiddleCenter;
            GUILayout.Label("一键穿衣");
            GUI.skin.label.fontSize = 12;
            GUI.skin.label.alignment = TextAnchor.MiddleCenter;
            GUILayout.Label("by:如梦");
            GUILayout.Space(10);
            GUI.skin.label.fontSize = 12;
            GUI.skin.label.alignment = TextAnchor.MiddleCenter;
            GUILayout.Label("支持模型一键绑定衣服");
            GUILayout.Space(10);
            avatar = (GameObject)EditorGUILayout.ObjectField("选择模型：", avatar, typeof(GameObject), true);
            cloth = (GameObject)EditorGUILayout.ObjectField("衣服：", cloth, typeof(GameObject), true);
            overlayMode = EditorGUILayout.Toggle("骨骼合并：", overlayMode);
            GUILayout.Space(10);

            EditorGUILayout.HelpBox("如过穿衣后出现异常，可关闭 骨骼合并 再试", MessageType.Info);
            if (avatar == null)
            {
                EditorGUILayout.HelpBox("请添加模型", MessageType.Warning);
            }
            else if (cloth == null)
            {
                EditorGUILayout.HelpBox("请添加衣服", MessageType.Warning);
            }
            if (GUILayout.Button("一键穿衣") && avatar != null && cloth != null)
            {
                ClearConsole();
                var newAvatar = AutoDressed(avatar, cloth, overlayMode);
                if (newAvatar != null)
                    avatar = newAvatar;
            }

            GUILayout.Space(50);
            EditorGUILayout.HelpBox("测试衣服是否合身？", MessageType.None);
            if (GUILayout.Button("打开动作播放器"))
                GetWindow(typeof(AvatarAnimationPlayer));

            GUILayout.EndScrollView();
        }

        private static GameObject AutoDressed(GameObject iAvatar, GameObject iCloth, bool overlayMode)
        {
            if (iAvatar.transform.Find(iCloth.name))
            {
                EditorUtility.DisplayDialog("警告", "模型中已有同名的衣服，请检查后再试", "确认");
                return null;
            }
            if (!iAvatar.transform.Find("Armature/Hips") || !iCloth.transform.Find("Armature/Hips"))
            {
                EditorUtility.DisplayDialog("警告", "模型骨骼异常，请检查模型、衣服是否带有Armature/Hips骨骼", "确认");
                return null;
            }

            // 克隆原模型
            GameObject avatar = Instantiate(iAvatar, iAvatar.transform.localPosition, Quaternion.identity);
            iAvatar.SetActive(false);
            avatar.SetActive(true);
            avatar.name = iAvatar.name + "_new";

            GameObject cloth = Instantiate(iCloth, iCloth.transform.localPosition, Quaternion.identity);
            iCloth.SetActive(false);
            cloth.SetActive(true);
            cloth.name = iCloth.name;
            cloth.transform.SetParent(avatar.transform);

            var clothArmature = GetAllChild(cloth.transform);

            var dynamicBoneMap = new Dictionary<DynamicBone, string>();

            // 检查DynamicBone
            foreach (var armature in clothArmature)
            {
                var dynamicBones = armature.Value.gameObject.GetComponents<DynamicBone>();
                foreach (var dynamicBone in dynamicBones)
                {
                    if (dynamicBone.m_Root != null)
                    {
                        var path = dynamicBone.m_Root.GetHierarchyPath();
                        path = path.Replace(cloth.transform.GetHierarchyPath() + "/", "");
                        dynamicBoneMap.Add(dynamicBone, path);
                    }
                }
            }

            // 移动GameObject
            var meshList = new List<SkinnedMeshRenderer>();
            foreach (var armature in clothArmature)
            {
                var path = armature.Key;
                var transform = armature.Value;
                if (path.StartsWith("Armature"))
                {
                    if (path.Equals("Armature"))
                    {
                        continue;
                    }
                    // 骨骼
                    var supArmature = avatar.transform.Find(path);
                    if (supArmature != null)
                    {
                        //骨骼已存在
                        if (!overlayMode)
                        {
                            transform.parent = supArmature;
                        }
                    }
                    else
                    {
                        supArmature = avatar.transform.Find(path.Substring(0, path.LastIndexOf("/")));
                        transform.parent = supArmature;
                    }
                }
                else
                {
                    // Mesh
                    var meshs = transform.GetComponents<SkinnedMeshRenderer>();
                    foreach (var mesh in meshs)
                    {
                        meshList.Add(mesh);
                    }
                }
            }

            // 合并模式
            if (overlayMode)
            {
                // 重新绑定骨骼
                try
                {
                    foreach (var mesh in meshList)
                    {
                        var bones = mesh.bones;
                        for (int i = 0; i < bones.Length; i++)
                        {
                            var path = bones[i].GetHierarchyPath();
                            path = path.Substring(path.IndexOf("Armature"));
                            bones[i] = avatar.transform.Find(path);
                        }
                        mesh.bones = bones;
                        mesh.rootBone = avatar.transform.Find("Armature/Hips");
                    }
                }
                catch (System.Exception)
                {
                    EditorUtility.DisplayDialog("错误", "衣服模型参数错误，请重新导入衣服文件再试", "确认");
                    return null;
                }

                // 重设DynamicBone参数
                foreach (var item in dynamicBoneMap)
                {
                    item.Key.m_Root = avatar.transform.Find(item.Value);
                }
            }

            // 删除Armature
            var cloth_armature = cloth.transform.Find("Armature").gameObject;

            if (cloth_armature.GetComponentsInChildren<DynamicBone>().Length == 0)
                DestroyImmediate(cloth_armature);
            DestroyImmediate(cloth_armature);

            Selection.activeObject = avatar;
            return avatar;
        }


        public static Dictionary<string, Transform> GetAllChild(Transform transform)
        {
            var map = new Dictionary<string, Transform>();
            GetAllChild2(transform, transform, ref map);
            map.Remove(transform.GetHierarchyPath());
            return map;
        }
        private static void GetAllChild2(Transform transform, Transform superTransform, ref Dictionary<string, Transform> list)
        {
            if (transform != superTransform)
            {
                var path = transform.GetHierarchyPath();
                path = path.Substring(superTransform.GetHierarchyPath().Length + 1);
                list.Add(path, transform);
            }
            if (transform.childCount == 0)
            {
                return;
            }
            else
            {
                foreach (Transform child in transform)
                {
                    GetAllChild2(child, superTransform, ref list);
                }
            }
        }
    }
}
#endif